# 计算机编码问题 本节主要讲计算机的编码存储格式和相应的变换。 ## 机器数和真值 先来说两个概念: - 机器数:在计算机中的二进制表示形式,是可以表示符号的,比如正负数 - 真值: 是计算机内真正的那个值,因为一般有一个`bit`表示符号位,所以看到的和实际表示并不一致 https://blog.csdn.net/qq_48486897/article/details/106653164 # 计算机所有存储都是补码,得到结果也是补码 a = 3 b = 5 print("3&b = {0}".format(a&b)) print("-1 & -2 = {0}".format(-1&-2)) print("-2 & 6 = {0}".format(-2 & 6)) # 位运算在乘除法中的应用 print(" 1x2={0}".format(1<<1)) print(" 1x16={0}".format(1<<4)) print(" -10x4={0}".format(-10<<2)) print(" -40/4={0}".format(-40>>2)) # 二进制表示法 print("10={0}".format(bin(10))) print("-10={0}".format(bin(-10))) # 2. 原码 - 符号位加上真值的绝对值 ```angularjs (+1)原码 = 0000 0001 (-1)原码 = 1000 0001 八位取值范围是[1111 1111 - 0111 1111] = [-127 - 127] ``` # 3. 反码 - 正数的反码是其本身 - 负数的反码是在原码的基础上,符号位不变,其余各位取反 ```angularjs [+1] = [0000 0001]原码 = [0000 0001]反码 [-1] = [1000 0001]原码 = [1111 1110]反码 ``` # 4. 补码 - 正数的补码是本身 - 负数的补码是原码基础上,符号位不变,各位取反,然后加1,即反码+1 # 5. 移码 - 补码的符号位取反 # 5. 为什么使用 - 1-1的问题 ```angularjs (1 - 1)原码表示 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2 (1 - 1)反码表示 = 1 + (-1) = [0000 0001]原 + [1000 0001]原= [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0 (1 - 1)补码表示 = 1 + (-1) = [0000 0001]原 + [1000 0001]原 = [0000 0001]补 + [1111 1111]补 = [0000 0000]补=[0000 0000]原 (-1) + (-127) = [1000 0001]原 + [1111 1111]原 = [1111 1111]补 + [1000 0001]补 = [1000 0000]补 ``` - -128只是一个表示方法,是-0表示的-128,不是计算出来的,计算出来的是错误的, ```angularjs [1000 0000]补码 = [0000 0000]原码 = 错误 ``` - 补码,修复了0的两个表示方法带来的问题,还可以表示一个最低位,所以八位二进制表示范围是[-128,127] # 编码问题 - 为什么需要编码 - 计算机本质上只能表示二进制 - 如何用一长串二进制表示复杂的信息 - 编码简史 - 二进制: - 数字->字符->数字 - 'a' -> 97 编码和解码 - 第一阶段: ASCII - 第二阶段:百花齐放,GB2312,GBK, BIG5 Latin1, ISO-8859-1, JIS, ANSI... - Latin1(ISO-8859-1) - 中国GBxxx - 韩国台湾Big5 - 日本JIS - ANSI-MBCS(Muilti-Bytes Charecter Set,多字节字符集) - Unicode+ISO # 编码表示法 - ASCII-American Standard Code for Information Interchange - 所有的控制字符(比如CR回车、DEL删除等)编码在0-31范围以及127中。 - 把所有的标点符号,英文大小写全部放在32-126范围中。 - 防止以后出现需要补充的情况,把128-255位这么多位置留出来, - 0xxxx xxxx, 高位为0 - Latin1 - 0-127的所有位置不动,那么可以兼容ASCII,二进制位0xxx xxxx - 128-255位置全部用完,二进制位1xxx xxxx - 128-159之间为控制字符, - 160-255位文字符号, - 其中包括了西欧语言、希腊语、泰语、阿拉伯语、希伯来语 - 欧元符号 - GBXXXXXXXXX - GB2312 - 如果一个字节中第一位为0,那么这就是一个ASCII字符。 -如果一个字节中第一位为1,那么这个是汉字,认定需要2个字节才表示一个编码的文字。 - 这个码表中包含汉字6763个和非汉字图形字符682个。 - 还有很多的空间没有用到,索性全部预留了吧。 - 0xxxxxxx:表示为ASCII字符 -1xxxxxxx 1xxxxxxx:表示为汉字 - GBK - 在GB2312基础上添加汉字 - 兼任GB2312和ASCII - 0xxxxxxx:表示为ASCII字符 - 1xxxxxxx xxxxxxxx:表示为汉字 - GB18030 - 2/4位混编 - Unicode - 只是一个码表,具体实现没有规定 - 0-0x10FFFF来映射这些字符,最多可以容纳1114112个字符 - 中文的编码范围为4E00-9FCF,其中9FC4-9FCF之间的区间没有使用 - 上述区间全部是汉字,不包含全角字符,不包含特殊文字 - UTF=UnicodeTransformationFormat - UTF-8 0x0000~0x007F (0 ~ 127) 1字节 0xxxxxxx 0x0080~0x07FF(128 ~ 2047) 110xxxxx 10xxxxxx 0x0800~FFFF(2048 ~ 65535) 3字节 1110xxxx 10xxxxxx 10xxxxxx 0x10000~1FFFFFF(65536 ~ 2097152) 4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 0x2000000~0x3FFFFFF 5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 0x4000000~0x7FFFFFFF 6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - UTF-16, 32 - UTF-16是早期Unicode遗留产物 - UTF-32浪费空间 - UCS-2 - UCS=UniversalCharacterSet,通用字符集 - UCS-2与Unicode相同 - 采用2个字节,定长的表示每一个字符,所以总计可以表示2^16个字符 - UCS-4 - 第一个字节:表示组(group),最高位为0,则有128个。 - 第二个字节:表示平面(plane),256个。 - 第三个字节:表示行(row),256个。 - 第四个字节:表示码位(cell),256个 - 如果UCS-4前两个字节为0, 则就是CUS-2 # 概念解释 - 大尾(BigEndian) 小尾(LittleEndian) - "汉" -> 6C49 - 6C49 -> BigEndian - 496C -> LittleEndian - BOM - UTF-8 无字节顺序问题 - UTF-16会出现问题: - "奎" -> 594E - "乙" -> 4E59 - BOM-ByteOrderMark - "ZERO WIDTH NO-BREAK SPACE" -> FEFF, 在UCS中不存在 - FEFF->BigEndian - FFFE->LittleEndian - UTF-8 用来表示编码, FEFF的UTF-8编码是EF BB BF, 用来表示此后编码是UTF-8编码 # Python的编码问题 - str - bytes - bytearray >>> b = bytes.fromhex('E4 B8 AD') >>> b b'\xe4\xb8\xad' >>> b.decode('utf-8') '中' >>> str(b) "b'\\xe4\\xb8\\xad'" >>> ord('A') 65 >>> ord('中') 20013 >>> chr(65) 'A' >>> chr(20013) '中' - len的单位是字符,不是字节 - python文件默认utf-8编码,如果特殊需要,需要声明 - 放在第一行,或者第二行 - ```# ‐*‐ coding: windows‐1252 ‐*‐``` - 读写文件默认utf-8, 可以指定 - code point方式比较字符串,可能会带来问题 - 重音符号的表示 - 使用 unicodedata.normalize 函数 - Python源码中出现了解码错误,那么会产生SyntaxError异常 - 其他情况下,如果发现编码解码错误,那么会产生UnicodeEncodeError, UnicodeDecodeError异常 # 参考资料 - https://www.cnblogs.com/jessonluo/p/4800331.html - https://blog.csdn.net/xuejianhui/article/details/52576771 - http://tools.jb51.net/table/gb2312 -